#define WIN32_LEAN_AND_MEAN

#include "../master.h"
#include <wininet.h>
#include <shellapi.h>
#include <commctrl.h>
#include <stdlib.h>
#include "../comfunct/comfunct.h"
#include "resource.h"
#include "update.h"
#include "u_wndproc.h"
#include "downplayer.h"

HFONT hfDefault = NULL, hfBold = NULL;
HWND hUpdateBox = NULL, hOrigWindow = NULL;
bool bStop = false;

UPDATE_EXPORT void UpdateClean()
{
    HINSTANCE hInstance = GetModuleHandle(TEXT("update.dll")); 
	SendMessage(FindWindow(TEXT("UpdateDialog"), NULL), WM_CLOSE, 0, 0);
    UnregisterClass(TEXT("UpdateDialog"), hInstance);
    return;
}

void ErrorExit(HINTERNET hInetHandle, bool bKillOrig)
{  
	if(hInetHandle != NULL)
    {
        InternetCloseHandle(hInetHandle);
    }
    UpdateClean();
    SetForegroundWindow(hOrigWindow);
    
    if(bKillOrig == true)
	{
        SendMessage(hOrigWindow, WM_CLOSE, 0, 0);
	}
    
    return;
}

void ControlCreate(HWND hwnd)
{     
    HWND hProgress = NULL, hProText = NULL, hStep1 = NULL, hStep2 = NULL, hStep3 = NULL, hStep4 = NULL, hHeaderText = NULL, hStopButton = NULL;
    LOGFONT lf = {0};
    const UINT iControls[] = {DLG_UPDATE_PROGRESS, DLG_HEADER_TEXT, DLG_PROGRESS, DLG_STEP1, DLG_STEP2,
                               DLG_STEP3, DLG_STEP4};
	HINSTANCE hAudioPlayer = GetModuleHandle(TEXT("AudioPlayer.exe"));
	HINSTANCE hInstance = GetModuleHandle(TEXT("update.dll"));
	HBITMAP hStopButtonPicture = NULL;
    
    hHeaderText = CreateWindow(TEXT("EDIT"), GetLocalText(94), WS_CHILD | SS_CENTER | WS_VISIBLE | WS_DISABLED | ES_READONLY, 35, 10, 275, 20, hwnd, (HMENU)DLG_HEADER_TEXT, hInstance, NULL);
    hProText = CreateWindow(TEXT("EDIT"), GetLocalText(95), WS_CHILD | WS_VISIBLE | WS_DISABLED | SS_LEFT | ES_READONLY, 15, 40, 100, 20, hwnd, (HMENU)DLG_UPDATE_PROGRESS, hInstance, NULL);
    hProgress = CreateWindow(TEXT("msctls_progress32"), GetLocalText(96), WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 27, 165, 290, 40, hwnd, (HMENU)DLG_PROGRESS, hInstance, NULL);
    hStep1 = CreateWindow(TEXT("EDIT"), GetLocalText(97), WS_CHILD | WS_VISIBLE | SS_LEFT | WS_DISABLED, 35, 65, 150, 20, hwnd, (HMENU)DLG_STEP1, hInstance, NULL);
    hStep2 = CreateWindow(TEXT("EDIT"), GetLocalText(98), WS_CHILD | WS_VISIBLE | SS_LEFT | WS_DISABLED, 35, 85, 150, 20, hwnd, (HMENU)DLG_STEP2, hInstance, NULL);
    hStep3 = CreateWindow(TEXT("EDIT"), GetLocalText(99), WS_CHILD | WS_VISIBLE | SS_LEFT | WS_DISABLED, 35, 105, 150, 20, hwnd, (HMENU)DLG_STEP3, hInstance, NULL);
    hStep4 = CreateWindow(TEXT("EDIT"), GetLocalText(100), WS_CHILD | WS_VISIBLE | SS_LEFT | WS_DISABLED, 35, 125, 150, 20, hwnd, (HMENU)DLG_STEP4, hInstance, NULL);
    hStopButton = CreateWindow(TEXT("BUTTON"), TEXT(""), WS_CHILD | BS_PUSHBUTTON | BS_BITMAP, 230, 50, 91, 94, hwnd, (HMENU)DLG_STOP_BUTTON, hInstance, NULL);
    hStopButtonPicture = (HBITMAP)LoadImage(hAudioPlayer, MAKEINTRESOURCE(DLG_STOP_DOWNLOADING), IMAGE_BITMAP, 0, 0, LR_SHARED);
    if(hStopButtonPicture == NULL)
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(101));
    }
    SendMessage(hStopButton, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hStopButtonPicture);
    ShowWindow(hStopButton, SW_SHOW);
    
    GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
    hfDefault = CreateFontIndirect(&lf);
	ChangeTextFont(hwnd, hfDefault);
    
    lf.lfWeight = 700;
    hfBold = CreateFontIndirect(&lf);     
    SendDlgItemMessage(hwnd, DLG_STEP1, WM_SETFONT, (WPARAM)hfBold, MAKELPARAM(TRUE, 0));
    return;
}

HANDLE DownloadAndWriteLocalFile(HINTERNET hConnection)
{
	BOOL bWriteSuccess = FALSE, bSent = FALSE;
    DWORD dwBytesDownloaded = 1, dwBytesWritten = 0, dwBytesToGet = 0, dwCount = 0;
    char* szIncomingFile = NULL;
    HANDLE hFile = NULL;

    HINTERNET hRequestParams = HttpOpenRequest(hConnection, TEXT("GET"), TEXT("update.txt"),
                               NULL, NULL, NULL, INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_RELOAD, 0);
    if(hRequestParams == NULL)
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(102));
        return NULL;
    }
    
    SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_DELTAPOS, 1, 0);
    
    bSent = HttpSendRequest(hRequestParams, NULL, 0L, NULL, 0);
    if(bSent == FALSE)
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(103));
        return NULL;
    }
    SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_DELTAPOS, 2, 0);
    
    SendDlgItemMessage(hUpdateBox, DLG_STEP1, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(TRUE, 0));
    SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_SETPOS, 0, 0);
    SendDlgItemMessage(hUpdateBox, DLG_STEP2, WM_SETFONT, (WPARAM)hfBold, MAKELPARAM(TRUE, 0));
    
    InternetQueryDataAvailable(hRequestParams, &dwBytesToGet, 0, 0);
     
    SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, (int)dwBytesToGet));
     
    szIncomingFile = malloc(dwBytesToGet);
     
    while(dwBytesDownloaded != 0) 
    {
        InternetReadFile(hRequestParams, &szIncomingFile[dwCount], dwBytesToGet - dwCount, &dwBytesDownloaded);
        dwCount += dwBytesDownloaded;
        SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_DELTAPOS, (int)dwBytesDownloaded, 0);
    
        if(bStop == TRUE)
        {
            InternetCloseHandle(hRequestParams);
            ErrorExit(hConnection, false);
            return NULL;     
        }
    }
    
    hFile = CreateFile(TEXT("update.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                       NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        
    if(hFile == NULL || hFile == INVALID_HANDLE_VALUE)
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(91));
        InternetCloseHandle(hRequestParams);
        ErrorExit(hConnection, false);
        return NULL;
    }
    
    if(bStop == TRUE)
    {
        InternetCloseHandle(hRequestParams);
        ErrorExit(hConnection, false);
        return NULL;
    }
    
    bWriteSuccess = WriteFile(hFile, szIncomingFile, dwBytesToGet, &dwBytesWritten, NULL);
    if(bWriteSuccess == FALSE)
    {
        ErrorInfo();
        DeleteFile(TEXT("update.txt"));
        ErrorMessage(GetLocalText(87));
        InternetCloseHandle(hRequestParams);
        ErrorExit(hConnection, false);
        return NULL;
    }
    
    free(szIncomingFile);
    
    if(bStop == true)
    {
        DeleteFile(TEXT("update.txt"));
        CloseHandle(hFile);
        InternetCloseHandle(hRequestParams);
        ErrorExit(hConnection, false);
        return NULL;     
    }
    CloseHandle(hFile);
    hFile = CreateFile(TEXT("update.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
    InternetCloseHandle(hRequestParams);
    return hFile;
}

UPDATE_EXPORT HWND UpdateDialog(HWND hwnd, const int iFileVersion)
{
    HMODULE hAudioPlayer = GetModuleHandle(NULL);
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), 0};
	RECT rc = {0};
	HINSTANCE hInstance = GetModuleHandle(TEXT("update.dll"));
	const TCHAR szUpdateClass[] = TEXT("UpdateDialog");

	bStop = false;

    if(GetClassInfoEx(hAudioPlayer, TEXT("AudioPlayer"), &wc) == 0)
	{
		ErrorInfo();
		ErrorMessage(GetLocalText(104));
		return NULL;
	}
    
    wc.lpszClassName = szUpdateClass;
    wc.lpfnWndProc = UpdateProc;
	wc.lpszMenuName = NULL;
	wc.hInstance = hInstance;
	wc.hbrBackground = NULL;
     
    if(!RegisterClassEx(&wc))
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(105));
        return NULL;
    }
     
    GetWindowRect(hwnd, &rc);
    hUpdateBox = CreateWindowEx(0, szUpdateClass, GetLocalText(106), WS_CAPTION | WS_SYSMENU | WS_POPUP, 
                                rc.left + 75, rc.top + 40, 350, 250, hwnd, 0, hInstance, (LPVOID)&iFileVersion);
    if(hUpdateBox == NULL)
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(107));
	    UnregisterClass(szUpdateClass, hInstance);
        return NULL;
    }
    ShowWindow(hUpdateBox, SW_SHOW);
    UpdateWindow(hUpdateBox);
    hOrigWindow = hwnd;
    return hUpdateBox;
}

DWORD WINAPI ThreadFunc(LPVOID lpParam)
{
    PPARAMS pParams = NULL;
    DWORD dwBytesRead = 0, dwFileSize = 0;
    HANDLE hUpdateText = NULL;
    char szFile[5] = "";
    int iDLversion = 0;
	HINTERNET hServerConnect = NULL;
      
    pParams = (PPARAMS)lpParam;
    SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, 4));
      
    hServerConnect = ServerConnect(pParams->hInitConnect, TEXT("thefanman2006.googlepages.com"));
    if(hServerConnect == NULL)
    {
        ErrorInfo();
		ErrorMessage(GetLocalText(108));
		ErrorExit(pParams->hInitConnect, false);
        return 0;
    }
    SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_DELTAPOS, 1, 0);
    hUpdateText = DownloadAndWriteLocalFile(hServerConnect);
    if(hUpdateText == NULL)
    {
        InternetCloseHandle(hServerConnect); 
		ErrorExit(pParams->hInitConnect, false);
        CloseHandle(hUpdateText);
        return 0;
    }
    dwFileSize = GetFileSize(hUpdateText, NULL);
    if(!ReadFile(hUpdateText, szFile, dwFileSize, &dwBytesRead, NULL))
    {
        ErrorInfo();
        ErrorMessage(GetLocalText(109));
		InternetCloseHandle(hServerConnect);
        ErrorExit(pParams->hInitConnect, false);
        CloseHandle(hUpdateText);
        return 0;
    }
    CloseHandle(hUpdateText);
    InternetCloseHandle(hServerConnect);
    InternetCloseHandle(pParams->hInitConnect);
     
    iDLversion = atoi(szFile);
     
    if(iDLversion > pParams->iFileVersion)
    {
        bool bUpdated = false;
        bUpdated = DownloadPlayerUpdate();
        if(bUpdated == false)
        {
            ErrorExit(pParams->hInitConnect, false);
            return 0;
        }
        SendDlgItemMessage(hUpdateBox, DLG_PROGRESS, PBM_SETPOS, 0, 0);
        SendDlgItemMessage(hUpdateBox, DLG_STEP3, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(TRUE, 0));
        SendDlgItemMessage(hUpdateBox, DLG_STEP4, WM_SETFONT, (WPARAM)hfBold, MAKELPARAM(TRUE, 0));
        MessageBox(hUpdateBox, GetLocalText(110), TEXT("AudioPlayer"), MB_OK | MB_ICONINFORMATION);
        ShellExecute(NULL, TEXT("open"), TEXT("audioplayer_setup.exe"), NULL, NULL, SW_SHOW);
        ErrorExit(pParams->hInitConnect, true);
    }
    else
    {
        ErrorMessage(GetLocalText(111));
        ErrorExit(pParams->hInitConnect, false);
    }
    return 1;
}
